package cn.iocoder.yudao.module.call.service.whiteaudit;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.call.controller.admin.agent.vo.AgentRespVO;
import cn.iocoder.yudao.module.call.convert.whiteAudit.WhiteAuditConverter;
import cn.iocoder.yudao.module.call.dal.dataobject.agent.AgentDO;
import cn.iocoder.yudao.module.call.dal.dataobject.speech.SpeechDO;
import cn.iocoder.yudao.module.call.dal.dataobject.vosnumber.VosNumberDO;
import cn.iocoder.yudao.module.call.dal.dataobject.whiteaudit.WhiteAuditAgentDO;
import cn.iocoder.yudao.module.call.dal.mysql.agent.AgentMapper;
import cn.iocoder.yudao.module.call.dal.mysql.vosnumber.VosNumberMapper;
import cn.iocoder.yudao.module.call.dal.mysql.whiteaudit.WhiteAuditAgentMapper;
import cn.iocoder.yudao.module.call.enums.WhiteAuditStatusEnum;
import cn.iocoder.yudao.module.call.service.location.LocationService;
import cn.iocoder.yudao.module.call.service.speech.SpeechService;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.module.call.controller.admin.whiteaudit.vo.*;
import cn.iocoder.yudao.module.call.dal.dataobject.whiteaudit.WhiteAuditDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.call.dal.mysql.whiteaudit.WhiteAuditMapper;

import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.call.enums.ErrorCodeConstants.*;


/**
 * 报白审批 Service 实现类
 *
 * @author 数创万维
 */
@Service
@Validated
public class WhiteAuditServiceImpl implements WhiteAuditService {

    @Resource
    private WhiteAuditMapper whiteAuditMapper;

    @Resource
    private WhiteAuditAgentMapper whiteAuditAgentMapper;

    @Resource
    private AgentMapper agentMapper;

    @Resource
    private LocationService locationService;

    @Resource
    private SpeechService speechService;

    @Resource
    private VosNumberMapper vosNumberMapper;

    @Override
    public Long createWhiteAudit(WhiteAuditSaveReqVO createReqVO) {
        // 插入
        WhiteAuditDO whiteAudit = BeanUtils.toBean(createReqVO, WhiteAuditDO.class);

        // 校验提交的资料是否齐全，如果不齐全，状态设置为0，待提交， result设置成错误信息
        // 如果符合资料， 状态设置为1，进行中。 然后调用service.submit接口提交给sdk执行api报白
        // 多个校验： 检查坐席是否填写了实名信息
        List<AgentDO> agentList = agentMapper.selectBatchIds(createReqVO.getAgentList());

        // 数量对不上
        if (agentList.size() != createReqVO.getAgentList().size()) {
            throw exception(AGENT_NOT_EXISTS);
        }
        // 检查坐席资料是否完整
        checkAgent(whiteAudit.getType(), agentList);

        whiteAudit.setStatus(WhiteAuditStatusEnum.WAITING.getValue());

        whiteAuditMapper.insert(whiteAudit);

        // 插入审核单下的坐席
        batchInsertAuditAgent(whiteAudit.getId(), agentList);

        return whiteAudit.getId();
    }

    private void batchInsertAuditAgent(Long id, List<AgentDO> agentList) {
        for (AgentDO agent : agentList) {
            WhiteAuditAgentDO auditAgentDO = new WhiteAuditAgentDO()
                    .setAgentId(agent.getId())
                    .setAuditId(id)
                    .setStatus(WhiteAuditStatusEnum.WAITING.getValue());
            whiteAuditAgentMapper.insert(auditAgentDO);
        }
    }

    private void checkAgent(int type, List<AgentDO> agentList) {
        Assert.notEmpty(agentList, "未选择坐席");
        agentList.forEach(agent -> {
            if (type == 2) {
                Assert.notEmpty(agent.getTelephone(), "坐席手机号不能为空");
            }
            Assert.notEmpty(agent.getRealName(), "坐席未填写真实姓名");
            Assert.notEmpty(agent.getIdNumber(), "坐席未填写身份证号");
        });
    }


    @Override
    public void submitAgent(WhiteAuditDealSaveReqVO saveReqVO) {
        List<Long> agentList = saveReqVO.getAgentList();
        WhiteAuditDO auditDO = whiteAuditMapper.selectById(saveReqVO.getAuditId());
        agentList.forEach(agent -> {
            WhiteAuditAgentDO auditAgentDO = whiteAuditAgentMapper.selectOne(WhiteAuditAgentDO::getAgentId, agent, WhiteAuditAgentDO::getAuditId, auditDO.getId());
            if (Objects.isNull(auditAgentDO)) {
                throw exception(WHITE_AUDIT_AGENT_NOT_EXISTS);
            }
            auditAgentDO.setStatus(saveReqVO.getStatus());
            auditAgentDO.setResult(saveReqVO.getResult());

            LambdaUpdateWrapper<AgentDO> updateWrapper = new LambdaUpdateWrapper<AgentDO>()
                    .set(AgentDO::getAuditResult, saveReqVO.getResult())
                    .eq(AgentDO::getId, auditAgentDO.getAgentId());
            if (ObjectUtil.equal(saveReqVO.getStatus(), WhiteAuditStatusEnum.SUCCESS.getValue())) {
                VosNumberDO vosNumberDO = vosNumberMapper.selectById(saveReqVO.getNumberId());

                // 找坐席，更新主叫 (简单硬编码一下)
                if (auditDO.getType() == 1) {
                    if (Objects.isNull(vosNumberDO)) {
                        throw exception(NUMBER_NOT_EXISTS);
                    }
                    updateWrapper.set(AgentDO::getSipCallAuditStatus, WhiteAuditStatusEnum.SUCCESS.getValue()).set(AgentDO::getSipCallNumber, vosNumberDO.getNumber());
                } else if (auditDO.getType() == 2) {
                    updateWrapper.set(AgentDO::getDoubleCallAuditStatus, WhiteAuditStatusEnum.SUCCESS.getValue());
                }
                // status=1 表示在用(已使用、已占用)
                vosNumberDO.setStatus(1);
                // setTenantId 表示被占用的企业id， 前端会展示企业名称
                vosNumberDO.setTenantId(auditDO.getTenantId());
                vosNumberMapper.updateById(vosNumberDO);
            } else {
                if (auditDO.getType() == 1) {
                    updateWrapper.set(AgentDO::getSipCallAuditStatus, WhiteAuditStatusEnum.FAIL.getValue());
                } else {
                    updateWrapper.set(AgentDO::getDoubleCallAuditStatus, WhiteAuditStatusEnum.FAIL.getValue());
                }
            }
            agentMapper.update(updateWrapper);
            whiteAuditAgentMapper.updateById(auditAgentDO);
        });
        // 遍历完之后查询一下该任务下的坐席列表， 如果存在status == 0 表示任务还没结束，否则给任务修改状态为结束；
        Long count = whiteAuditAgentMapper.selectCount(new LambdaQueryWrapperX<WhiteAuditAgentDO>().eq(WhiteAuditAgentDO::getAuditId, auditDO.getId()).eq(WhiteAuditAgentDO::getStatus, WhiteAuditStatusEnum.WAITING.getValue()));
        if (count == 0) {
            // 任务结束
            auditDO.setStatus(WhiteAuditStatusEnum.SUCCESS.getValue());
            whiteAuditMapper.updateById(auditDO);
        }

    }

    @Override
    public void updateWhiteAudit(WhiteAuditUpdateReqVO updateReqVO) {
        // 先查询
        WhiteAuditDO updateObj = whiteAuditMapper.selectById(updateReqVO.getId());
        updateObj.setStatus(updateReqVO.getStatus()).setNumber(updateReqVO.getNumber()).setResult(updateObj.getResult());
        if (ObjectUtil.equal(WhiteAuditStatusEnum.SUCCESS.getValue(), updateReqVO.getStatus())) {
            // 全部通过
            whiteAuditAgentMapper.update(new LambdaUpdateWrapper<WhiteAuditAgentDO>()
                    .set(WhiteAuditAgentDO::getStatus, WhiteAuditStatusEnum.SUCCESS.getValue())
                    .eq(WhiteAuditAgentDO::getAuditId, updateReqVO.getId())
            );
            // 找到坐席id， 更新主叫 (只有vos点呼群呼类型的才会更新主叫)
            List<WhiteAuditAgentDO> list = whiteAuditAgentMapper.selectList(WhiteAuditAgentDO::getAuditId, updateReqVO.getId());
            List<Long> agentIdList = list.stream().map(WhiteAuditAgentDO::getAgentId).collect(Collectors.toList());

            if (updateObj.getType() == 1) {
                agentMapper.update(new LambdaUpdateWrapper<AgentDO>()
                        .set(AgentDO::getSipCallNumber, updateReqVO.getNumber())
                        .set(AgentDO::getSipCallAuditStatus, 1)
                        .in(AgentDO::getId, agentIdList)
                );
            } else {
                agentMapper.update(new LambdaUpdateWrapper<AgentDO>()
                        .set(AgentDO::getDoubleCallAuditStatus, 1)
                        .in(AgentDO::getId, agentIdList)
                );
            }

        } else if (ObjectUtil.equal(WhiteAuditStatusEnum.FAIL.getValue(), updateReqVO.getStatus())) {
            whiteAuditAgentMapper.update(new LambdaUpdateWrapper<WhiteAuditAgentDO>().set(WhiteAuditAgentDO::getStatus, WhiteAuditStatusEnum.FAIL.getValue()).eq(WhiteAuditAgentDO::getAuditId, updateReqVO.getId()));
        }
        whiteAuditMapper.updateById(updateObj);
    }

    public List<WhiteAuditAgentDO> getWhiteAuditAgentList(Long auditId) {
        return whiteAuditAgentMapper.selectList(WhiteAuditAgentDO::getAuditId, auditId);
    }

    @Override
    public WhiteAuditRespVO getWhiteAudit(Long id) {
        WhiteAuditDO auditDO = whiteAuditMapper.selectById(id);
        if (Objects.isNull(auditDO)) {
            throw exception(WHITE_AUDIT_NOT_EXISTS);
        }

        Map<Long, SpeechDO> speechDOMap = speechService.getSpeechMap(Collections.singletonList(auditDO.getSpeechId()));
        WhiteAuditRespVO respVO = WhiteAuditConverter.INSTANCE.convert2(auditDO, speechDOMap);

        // 还需映射坐席状态
        List<WhiteAuditAgentDO> auditAgentList = getWhiteAuditAgentList(id);

        // 坐席列表
        if (CollectionUtil.isNotEmpty(auditAgentList)) {
            List<AgentDO> agentDOList = agentMapper.selectBatchIds(auditAgentList.stream().map(WhiteAuditAgentDO::getAgentId).collect(Collectors.toList()));
            respVO.setAgentList(BeanUtils.toBean(agentDOList, AgentRespVO.class));
        }
        return respVO;
    }

    @Override
    public PageResult<WhiteAuditDO> getWhiteAuditPage(WhiteAuditPageReqVO pageReqVO) {
        return whiteAuditMapper.selectPage(pageReqVO);
    }

//    @Override
//    public void dealAudit(WhiteAuditDealSaveReqVO reqVO) {
//        WhiteAuditDO auditDO = whiteAuditMapper.selectById(reqVO.getId());
//        if (Objects.isNull(auditDO)) {
//            throw exception(WHITE_AUDIT_NOT_EXISTS);
//        }
//        // 验证状态是否为process, 且坐席不为空，且归属地不为空
//        if (Objects.isNull(auditDO.getNumberPoolId())) {
//            throw exception(WHITE_AUDIT_NUMBER_POOL_IS_NULL);
//        }
//        if (CollectionUtil.isEmpty(whiteAuditAgentMapper.selectList(WhiteAuditAgentDO::getAuditId, reqVO.getId()))) {
//            throw exception(WHITE_AUDIT_AGENT_IS_EMPTY);
//        }
//        if (ObjectUtil.equal(auditDO.getStatus(), WhiteAuditStatusEnum.SUCCESS.getValue()) || ObjectUtil.equal(auditDO.getStatus(), WhiteAuditStatusEnum.FAIL.getValue())) {
//            throw exception(WHITE_AUDIT_IS_DEAL, WhiteAuditStatusEnum.getMsg(auditDO.getStatus()));
//        }
//        auditDO.setStatus(reqVO.getStatus()).setResult(reqVO.getResult());
//        whiteAuditMapper.updateById(auditDO);
//
//        // 如果是审批通过，就把所有坐席状态修改为加白
//
//        if (ObjectUtil.equal(reqVO.getStatus(), WhiteAuditStatusEnum.SUCCESS.getValue())) {
//            whiteAuditAgentMapper.update(new LambdaUpdateWrapper<WhiteAuditAgentDO>().set(WhiteAuditAgentDO::getStatus, reqVO.getStatus()).eq(WhiteAuditAgentDO::getAuditId, reqVO.getId()));
//
//        }
//
//    }
}